package co.saen.nextincloud.beans;

import co.saen.nextincloud.dao.ProfilesDAO;
import co.saen.nextincloud.dao.UsersDAO;
import co.saen.nextincloud.model.Profiles;
import co.saen.nextincloud.model.Users;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

/**
 * Este Bean maneja todos los accesos a la clase UsersDAO, se requiere para las
 * operaciones de las vistas users.xhtml y dialogs.xhtml. Búsqueda, creación y
 * actualización de los registros de la tabla users
 *
 * @author Felipe Rolvar
 */
@ManagedBean
@SessionScoped
public class UserBean implements Serializable {
    //<editor-fold defaultstate="collapsed" desc="Variables, Setters y Getters">
    /**
     * Declaración de variables locales
     *
     * user: objeto tipo user que contendrá todos los datos de la tabla users
     * users: objeto tipo List que sera el listado de los usuarios que se
     * encuentran en la base de datos usrPrfCode: variable tipo String que sirve
     * para la búsqueda de un perfil asignado a un usuario nuevo, devuelve un
     * objeto de tipo Profile mediante el método ProfileDAO.searchByID() y lo
     * asigna al campo user.setProfiles
     */
    private Users user;
    private List<Users> users;
    private String usrPrfCode;
    private Boolean Inactive = false;

    public String getUsrPrfCode() {
        return usrPrfCode;
    }

    public void setUsrPrfCode(String usrPrfCode) {
        this.usrPrfCode = usrPrfCode;
    }

    public Users getUser() {
        if (user == null) {
            user = new Users();
        }
        return user;
    }

    public void setUser(Users user) {
        this.user = user;
    }

    public List<Users> getUsers() {
        UsersDAO usersDAO = new UsersDAO();
        users = usersDAO.allUsers(Inactive);
        return users;
    }
//</editor-fold>
    //<editor-fold defaultstate="collapsed" desc="Preparación Transacciones CRUD">

    /**
     * El método selectUser es usado previo a las transacciones UpdateUser y
     * DeleteUser lo que realiza básicamente es asignar al objeto user el
     * usuario actual que se desea eliminar o editar.
     */
    public void selectUser(String code) {
        UsersDAO usersDao = new UsersDAO();
        user = usersDao.searchByCode(code);
        usrPrfCode = user.getProfiles().getPrfCode();
    }

    /**
     * La función selectProfile devuelve un objeto tipo Profiles dado un
     * parámetro de entrada tipo String.
     *
     * @param prfCode
     * @return Profile
     */
    public Profiles selectedProfile(String prfCode) {
        usrPrfCode = "";
        ProfilesDAO profilesDAO = new ProfilesDAO();
        return profilesDAO.searchProfileById(prfCode);
    }

    /**
     * El método prepareCreate es usado previo a las transacciones CreateUser
     * inicializa un objeto tipo User para la asignación de valres y su
     * posterior grabación en la base de datos
     */
    public void prepareCreate() {
        user = new Users();
    }

    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Transacciones CRUD">
    /**
     * Estos métodos llaman al procedimiento transactions con un parámetro de
     * entrada tipo char c = create o crear u = update o actualizar d = delete o
     * eliminar
     *
     * @see #transactions(char)
     */
    public void createUser() {
        user.setProfiles(selectedProfile(usrPrfCode));
        user.setUsrLastLogin(stringToDate("01/01/2000"));
        transactions('c');
        Inactive = false;
    }

    public void updateUser() {
        user.setProfiles(selectedProfile(usrPrfCode));
        transactions('u');
    }

    public void deleteUser() {
        transactions('d');
    }

    public void transactions(char type) {
        String resultado = "";
        String sucess = "";
        UsersDAO usersDAO = new UsersDAO();
        switch (type) {
            case 'c': //create
                resultado = usersDAO.createUser(user);
                sucess = "Usuario Creado Correctamente";
                break;
            case 'u': //update
                resultado = usersDAO.updateUser(user);
                sucess = "Usuario Actualizado Correctamente";
                break;
            case 'd': //delete
                resultado = usersDAO.deleteUser(user);
                sucess = "Usuario Eliminado Correctamente";
                break;
        }
        FacesContext context = FacesContext.getCurrentInstance();
        if (resultado.equals("ok")) {
            context.addMessage(null, new FacesMessage(sucess, null));
        } else {
            context.addMessage(null, new FacesMessage("Error: " + resultado, null));
        }
    }

    // </editor-fold>
    //<editor-fold defaultstate="collapsed" desc="otras funciones y métodos">
    /**
     * Funcion devuelve un objeto Date con un parámetro de entrada tipo String
     *
     * @param fecha variable tipo String
     * @return fechaDate variable tipo Date
     */
    public Date stringToDate(String fecha) {
        SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
        String strFecha = fecha;
        Date fechaDate = null;
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            fechaDate = formato.parse(strFecha);
            return fechaDate;
        } catch (ParseException ex) {
            context.addMessage(null, new FacesMessage(ex.getMessage(), null));
            return fechaDate;
        }
    }

    /**
     * Esta acción es llamada desde el botón de revisar inactivos establece el
     * valor de la variable Inactive a True y en la vista se carga la tabla con
     * los usuarios inactivos de acuerdo al método ya creado <List> Users
     * getUsers()
     */
    public void inactiveUsers(Boolean includeInactive) {
        this.Inactive = includeInactive;
    }

    /**
     * El siguiente método realiza la activación de un usuario que se encuentre
     * inactivo. como parámetro de entrada recibe un objeto tipo usuario que es
     * pasado a traves de la vista, se actualiza su estado usrActv y se ejecuta
     * el procedimineto updateUser de la clase UsersDAO
     */
    public void activeUser(Users user) {
        user.setUsrActv(Boolean.TRUE);
        String resultado;
        UsersDAO usersDAO = new UsersDAO();
        resultado = usersDAO.updateUser(user);
        FacesContext context = FacesContext.getCurrentInstance();
        if (resultado.equals("ok")) {
            context.addMessage(null, new FacesMessage("El usuario se activó correctamente", null));
        } else {
            context.addMessage(null, new FacesMessage("Error: " + resultado, null));
        }
        Inactive = Boolean.FALSE;
    }
    //</editor-fold>
}